// 一次匹配，提取多个
#include <stdio.h>
#include <stdlib.h>
#include <regex.h>

// 输出字符串中指定范围内的字符
void print_substr(const char* s, size_t __start, size_t __end);

int main (int argc, char** argv)
{
    int n;
    // 正则编译缓存
    regex_t pat_buf;
    // 记录分组匹配数据
    regmatch_t *pmatch = NULL;

    // 正则表达式
    char* pat_str = "([0-9]+) apples.* ([0-9]+) oranges";
    // 被匹配字符串
    char* str = "I have 20 apples and 34 oranges.";

    // 编译正则表达式
    regcomp(&pat_buf, pat_str, REG_EXTENDED|REG_NEWLINE);

    // 分配匹配位置结果结构体数组(匹配寄存器数组)
    pmatch = (regmatch_t*)malloc((pat_buf.re_nsub + 1) * sizeof(regmatch_t));

    printf("There can be %ld captures\n", pat_buf.re_nsub);

    // 正则匹配，返回0表示匹配成功
    n = regexec(&pat_buf, str, pat_buf.re_nsub + 1, pmatch, 0);
    if(n != 0)
    {
        printf("Nothing matched with %s\n", str);

        free(pmatch);
        regfree(&pat_buf);

        return 0;
    }

    // 输出匹配结果
    if(pmatch[0].rm_so != -1)
    {
        // 整体匹配结果
        printf("Matched part = ");
        print_substr(str, pmatch[0].rm_so, pmatch[0].rm_eo);
        // 第1分组匹配结果
        printf("Apple = ");
        print_substr(str, pmatch[1].rm_so, pmatch[1].rm_eo);
        // 第2分组匹配结果
        printf("Orange = ");
        print_substr(str, pmatch[2].rm_so, pmatch[2].rm_eo);
    };

    // 释放空间
    free(pmatch);
    regfree(&pat_buf);

    return 0;
}

/* 输出字符串中指定范围的字符 */
void print_substr(const char* s, size_t __start, size_t __end)
{
    int i;

    if(s)
    {
        for(i = __start; i < __end; ++i)
        {
            putchar(s[i]);
        }
    }

    putchar('\n');
}
